﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Eco.Handles;
using CommonClasses.Utility;
using System.IO;
using System.Windows.Forms;
using segDroopyEyes.Eco.Services.XmlQueryService2;
using Eco.ObjectRepresentation;
using Eco.Services;
using uCoreInterfaces2;
using CommonClasses.Logger;
using Descriptions_DomainModel.Model;

namespace Project.Model
{
    /// <summary> Класс для сохранения\открытия файлов проекта 
    /// (взятие сохраняемых классов и загрузка восстанавливаемых 
    /// происходит непосредственно через EcoSpace)
    /// </summary>
    public class ProjectLoader
    {

        public readonly string DocumentTypesExtension = "plugins.ih3.config";
        public readonly string ProjectDataExtension = "ihprj";
        public readonly string FoldersExtension = "ihprj.folders";

        private const string DocumentTypesQuery = "SaveDocumentTypesQuery.xmlq";
        private const string SaveProjectDataQuery = "SaveProjectDataQuery.xmlq";
        private const string SaveFoldersQuery = "SaveFoldersQuery.xmlq";


        /// <summary> Папка, в которой лежат запросы к EcoSpace
        /// </summary>
        private string queriesDirectory;


        /// <summary> Служебное поле для хранения ecoSpace
        /// </summary>
        private IEcoServiceProvider ecoSpace;


        /// <summary> Конструктор загрузчика 
        /// </summary>
        /// <param name="ecoSpace">ecoSpace</param>
        /// <param name="queriesDirectory">путь до файлов с запросами</param>
        /// <param name="loggingManagment">Среда для создания собственного лога</param>
        public ProjectLoader(IEcoServiceProvider ecoSpace, string queriesDirectory)
        {
            this.ecoSpace = ecoSpace;
            this.queriesDirectory = queriesDirectory;
        }


        /// <summary> Загрузить типы документов из файла
        /// </summary>
        /// <param name="fileName">Имя файла</param>
        public void LoadDocumentTypesFromFile(string fileName)
        {
            if (!File.Exists(fileName))
                throw new LoadingDocTypesException("Отсутствует файл с типами документов: " + fileName);

            var dess = ecoSpace.GetEcoService<IXmlSerializerService>();
            PathUtility.RestoreCurrentDirectory(Locality.ExeFile);
            try
            {
                dess.LoadFromFile(fileName);
            }
            catch (Exception e)
            {
                throw new LoadingDocTypesException("Ошибка чтения списка типов документов из файла: " + fileName);
            }

        }


        /// <summary> Сохранить типы документов в файл
        /// </summary>
        /// <param name="fileName">Имя файла</param>
        public void SaveDocumentTypesToFile(string fileName)
        {
            var sserv = ecoSpace.GetEcoService<IXmlQueryServiceSEG>();
            sserv.ExeXmlFile2XmlFile(null, queriesDirectory + DocumentTypesQuery, "", fileName);
        }


        /// <summary> 
        /// Сохранить проект в файл
        /// </summary>
        /// <param name="fileName">Имя файла без расширения</param>
        public void SaveProjectDataToFile(string FilePath)
        {
            var sserv = ecoSpace.GetEcoService<IXmlQueryServiceSEG>();

            PathUtility.RestoreCurrentDirectory(Locality.ExeFile);
            //сохраняем проект
            sserv.ExeXmlFile2XmlFile(null, queriesDirectory + "\\" + SaveProjectDataQuery, "", FilePath + "." + ProjectDataExtension);

            ProjectData pd = ecoSpace.GetEcoService<IOclService>().Evaluate("ProjectData.allInstances->First").AsObject as ProjectData;

            if (pd.ProjectType == ProjectType.Usual)
            {
                PathUtility.RestoreCurrentDirectory(Locality.ExeFile);
                //сохраняем виртуальные папки
                sserv.ExeXmlFile2XmlFile(null, queriesDirectory + "\\" + SaveFoldersQuery, "", FilePath + "." + FoldersExtension);
            }
        }


        /// <summary> Загрузить проект из файла
        /// </summary>
        /// <param name="fileName">Имя файла без расширения</param>
        public void LoadProjectDataFromFile(string fileName)
        {
            string filePath = fileName + "." + ProjectDataExtension;
            string foldersPath = fileName + "." + FoldersExtension;

            var dess = ecoSpace.GetEcoService<IXmlSerializerService>();


            #region Проверка на наличие необходимых файлов

            //путь до файла с виртуальными папками
            var folders = Path.GetDirectoryName(filePath) +
                    ((Path.GetDirectoryName(filePath) == string.Empty) ? "" : Path.DirectorySeparatorChar.ToString()) +
                    Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(filePath)) + "." +
                    FoldersExtension;

            if (!File.Exists(filePath))
                throw new LoadingProjectException("Отсутствует главный файл проекта: " + fileName);

            #endregion

            PathUtility.RestoreCurrentDirectory(Locality.ExeFile);

            try
            {
                //открываем файл с проектом
                dess.LoadFromFile(filePath);

                ProjectData pd = ecoSpace.GetEcoService<IOclService>().Evaluate("ProjectData.allInstances->First").AsObject as ProjectData;

                if (pd.ProjectTypeAsString == "Usual")
                {
                    if (!File.Exists(foldersPath))
                        throw new LoadingProjectException("Отсутствует один из файлов проекта:" + folders);
                    //открываем файл с папками
                    dess.LoadFromFile(foldersPath);
                }
            }
            catch (Exception e)
            {
                throw new LoadingProjectException("Ошибка при чтении файла данных проекта. " + e.Message);
            }
        }
    }
}
